#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import platform

from oracle import logger
from common.common import execute_cmd_list
from common.common import read_result_file
from common.const import ExecuteResultEnum
from oracle.common.constants import SHELL_PROFILE

user_sell_type = 'bash'
oracle_home_path = ""
oracle_base_path = ""


def get_asm_user_env_by_linux(asm_install_user_name, asm_instance_name: str = ''):
    asm_user_env = ''
    asm_user_sell_type = 'bash'
    user_name_lines = read_result_file("/etc/passwd").splitlines()
    for line in user_name_lines:
        if line.startswith(f"{asm_install_user_name}:"):
            asm_user_sell_type = line.split('/')[-1]
            break
    if asm_user_sell_type == 'csh':
        asm_user_env += "setenv NLS_LANG American_America.US7ASCII;"
        if asm_instance_name:
            asm_user_env += f"setenv ORACLE_SID {asm_instance_name};"
    else:
        asm_user_env += "export NLS_LANG=American_America.US7ASCII;"
        if asm_instance_name:
            asm_user_env += f"export ORACLE_SID={asm_instance_name};"
    cmd_list = [f"cat /etc/oracle/olr.loc", f"grep 'crs_home'"]
    return_code, crs_home_path, err_str = execute_cmd_list(cmd_list)
    logger.info(f"return_code={return_code},crs_home_path={crs_home_path},err_str={err_str}")
    if int(return_code) != ExecuteResultEnum.SUCCESS.value:
        logger.error(f"cannot find crs_home from olr.loc, cmd:{cmd_list}")
        return asm_user_env
    crs_home_path = crs_home_path.split('=')[1].strip()
    if crs_home_path:
        if asm_user_sell_type == 'csh':
            asm_user_env += f"setenv ORACLE_HOME {crs_home_path};setenv PATH {crs_home_path}/bin:$PATH;"
        else:
            asm_user_env += f"export ORACLE_HOME={crs_home_path};export PATH={crs_home_path}/bin:$PATH;"
    logger.info(f"grid_user_env:{asm_user_env}")
    return asm_user_env


def get_user_shell_type(user_name):
    global user_sell_type
    if platform.system().lower() == "windows":
        return user_sell_type
    user_name_lines = read_result_file("/etc/passwd").splitlines()
    for line in user_name_lines:
        if line.startswith(f"{user_name}:"):
            user_sell_type = line.split('/')[-1]
            break
    logger.info(f"get_user_shell_type:{user_sell_type}")
    return user_sell_type


def update_oracle_env(oracle_base="", oracle_home=""):
    if oracle_base:
        update_oracle_base_path(oracle_base)
    if oracle_home:
        update_oracle_home_path(oracle_home)


def update_oracle_home_path(oracle_home):
    global oracle_home_path
    oracle_home_path = oracle_home
    logger.info(f"oracle_home_path:{oracle_home_path}")


def update_oracle_base_path(oracle_base):
    global oracle_base_path
    oracle_base_path = oracle_base
    logger.info(f"oracle_base_path:{oracle_base_path}")


def get_oracle_user_env_by_linux(instance_name: str = '', pdb_name: str = ''):
    global oracle_home_path
    global user_sell_type
    global oracle_base_path
    oracle_user_env = ''
    if user_sell_type == 'csh':
        oracle_user_env += "setenv NLS_LANG American_America.US7ASCII;"
        if oracle_base_path:
            oracle_user_env += f"setenv ORACLE_BASE {oracle_base_path};"
        if oracle_home_path:
            oracle_user_env += f"setenv ORACLE_HOME {oracle_home_path};setenv PATH {oracle_home_path}/bin:$PATH;"
        if instance_name:
            oracle_user_env += f"setenv ORACLE_SID {instance_name};"
        if pdb_name:
            oracle_user_env += f"setenv ORACLE_PDB_SID {pdb_name};"
        else:
            oracle_user_env += f"unsetenv ORACLE_PDB_SID;"
    else:
        oracle_user_env += "export NLS_LANG=American_America.US7ASCII;export LANG=c;"
        if oracle_base_path:
            oracle_user_env += f"export ORACLE_BASE={oracle_base_path};"
        if oracle_home_path:
            oracle_user_env += f"export ORACLE_HOME={oracle_home_path};export PATH={oracle_home_path}/bin:$PATH;"
        if instance_name:
            oracle_user_env += f"export ORACLE_SID={instance_name};"
        if pdb_name:
            oracle_user_env += f"export ORACLE_PDB_SID={pdb_name};"
        else:
            oracle_user_env += f"unset ORACLE_PDB_SID;"
    logger.info(f"oracle_user_env:{oracle_user_env}")
    return oracle_user_env


def user_shell_type(user_name):
    shell_type = "bash"
    user_name_lines = read_result_file("/etc/passwd").splitlines()
    for line in user_name_lines:
        if line.startswith(f"{user_name}:"):
            shell_type = line.split('/')[-1]
            break
    logger.info(f"get_user_shell_type:{shell_type}")
    return shell_type


def build_user_env(user_name, inst_name="", pdb_name=""):
    import pwd
    shell_type = user_shell_type(user_name)
    user_info = pwd.getpwnam(user_name)
    home_dir = user_info.pw_dir
    logger.info(f"home_dir:{home_dir},shell_type:{shell_type}")
    user_env = ""
    global oracle_base_path
    global oracle_home_path
    if shell_type != "csh":
        existing_profiles = [
            f". ~/{item};"
            for item in SHELL_PROFILE.get(shell_type, [])
            if os.path.exists(os.path.join(home_dir, item))]
        logger.info(f"existing_profiles:{existing_profiles}")
        user_env += " ".join(existing_profiles)
        user_env += " export NLS_LANG=American_America.US7ASCII;export LANG=c;"
        if oracle_base_path:
            user_env += f"export ORACLE_BASE={oracle_base_path};"
        if oracle_home_path:
            user_env += f"export ORACLE_HOME={oracle_home_path};export PATH={oracle_home_path}/bin:$PATH;"
        if inst_name:
            user_env += f"export ORACLE_SID={inst_name};"
        if pdb_name:
            user_env += f"export ORACLE_PDB_SID={pdb_name};"
        else:
            user_env += f"unset ORACLE_PDB_SID;"
    else:
        user_env += "setenv NLS_LANG American_America.US7ASCII;setenv LANG=c;"
        if oracle_base_path:
            user_env += f"setenv ORACLE_BASE={oracle_base_path};"
        if oracle_home_path:
            user_env += f"setenv ORACLE_HOME {oracle_home_path};setenv PATH {oracle_home_path}/bin:$PATH;"
        if inst_name:
            user_env += f"setenv ORACLE_SID {inst_name};"
        if pdb_name:
            user_env += f"setenv ORACLE_PDB_SID {pdb_name};"
        else:
            user_env += f"unsetenv ORACLE_PDB_SID;"
    return user_env
